<!--
  ~
  ~  Copyright (c) 2018-2025, Pactera JinXin Software All rights reserved.
  ~
  -->

<template>
    <div class="app-container calendar-list-container">
        <basic-container>
            <div class="filter-container">
                <el-button-group>
                    <el-button v-if="menuManager_btn_add" type="primary" icon="plus" @click="handlerAdd">添加</el-button>
                    <el-button v-if="menuManager_btn_edit" type="primary" icon="edit" @click="handlerEdit">编辑</el-button>
                    <el-button v-if="menuManager_btn_del" type="primary" icon="delete" @click="handleDelete">删除</el-button>
                </el-button-group>
            </div>

            <el-row class="madp-mt">
                <el-col :span="8">
                    <el-tree
                        v-loading="loading"
                        :data="treeData"
                        :default-expanded-keys="aExpandedKeys"
                        :filter-node-method="filterNode"
                        :props="defaultProps"
                        class="filter-tree"
                        node-key="id"
                        highlight-current
                        @node-click="getNodeData"
                        @node-expand="nodeExpand"
                        @node-collapse="nodeCollapse"
                    />
                </el-col>
                <el-col :span="16">
                    <el-card class="box-card">
                        <el-form ref="form" :label-position="labelPosition" :model="form" :rules="rules" label-width="120px">
                            <el-form-item label="父级节点" prop="parentId">
                                <el-input v-model.trim="form.parentId" :disabled="true" placeholder="请输入父级节点" />
                            </el-form-item>
                            <el-form-item v-if="form.menuId" label="节点ID" prop="menuId">
                                <el-input v-model.trim="form.menuId" :disabled="formEdit || formStatus === 'update'" type="number" placeholder="请输入节点ID" />
                            </el-form-item>
                            <el-form-item label="标题" prop="name">
                                <el-input v-model.trim="form.name" :disabled="formEdit" maxlength="20" placeholder="请输入标题" />
                            </el-form-item>
                            <el-form-item label="类型" prop="type">
                                <el-radio v-model="form.type" :disabled="formEdit || isEdit" label="0">菜单</el-radio>
                                <el-radio v-model="form.type" :disabled="formEdit || isEdit" label="1">按钮</el-radio>
                            </el-form-item>

                            <el-form-item v-if="form.type === '1'" label="权限标识" prop="permission">
                                <el-input v-model.trim="form.permission" :disabled="formEdit" placeholder="请输入权限标识" />
                            </el-form-item>
                            <el-form-item v-if="form.type === '0'" label="地址" prop="path">
                                <el-input v-model.trim="form.path" :disabled="formEdit" maxlength="128" placeholder="/xx/xxx || http://" />
                            </el-form-item>
                            <el-form-item v-if="form.type === '0'" label="图标" prop="icon">
                                <avue-icon-select v-model="form.icon" :icon-list="iconList" :disabled="formEdit" placeholder="请输入图标" />
                            </el-form-item>
                            <el-form-item v-if="form.type === '0'" label="排序" prop="sort">
                                <el-input v-model.trim="form.sort" :disabled="formEdit" type="number" min="-999" max="999" placeholder="请输入排序" />
                            </el-form-item>
                            <el-form-item v-if="form.type === '0'" label="路由缓冲" prop="type">
                                <el-switch v-model="form.keepAlive" :disabled="formEdit" :active-value="'0'" :inactive-value="'1'" active-color="#13ce66" inactive-color="#ff4949" />
                            </el-form-item>
                            <el-form-item v-if="formStatus === 'update'">
                                <el-button type="primary" @click="update">更新</el-button>
                                <el-button @click="onCancel">取消</el-button>
                            </el-form-item>
                            <el-form-item v-if="formStatus === 'create'">
                                <el-button type="primary" @click="create">保存</el-button>
                                <el-button @click="onCancel">取消</el-button>
                            </el-form-item>
                        </el-form>
                    </el-card>
                </el-col>
            </el-row>
        </basic-container>
    </div>
</template>

<script>
import { addObj, delObj, fetchMenuTree, getObj, putObj } from '@/api/admin/menu';
import { mapGetters } from 'vuex';
import iconList from '@/const/icon-list';

export default {
    name: 'Menu',
    filters: {
        typeFilter(type) {
            const typeMap = {
                0: '菜单',
                1: '按钮'
            };
            return typeMap[type];
        }
    },
    data() {
        return {
            loading: false, // loading开关
            tempForm: {}, // 编辑表单
            iconList: iconList, // 图标库
            formEdit: true, // 表单编辑状态
            isEdit: false, // 是否编辑
            formStatus: '', // 表单状态
            typeOptions: ['0', '1'],
            listQuery: {
                name: undefined
            },
            treeData: [], // 表格数据
            oExpandedKey: {
                // key (from tree id) : expandedOrNot boolean
            },
            oTreeNodeChildren: {
                // id1 : [children] (from tree node id1)
                // id2 : [children] (from tree node id2)
            },
            aExpandedKeys: [], // 默认展开的key
            // 树组件的props键名
            defaultProps: {
                children: 'children',
                label: 'name'
            },
            labelPosition: 'right', // 表单label位置
            // 表单对象
            form: {
                permission: undefined,
                name: undefined,
                menuId: undefined,
                parentId: undefined,
                icon: undefined,
                sort: undefined,
                component: undefined,
                type: undefined,
                path: undefined
            },
            // 当前树组件选中id
            currentId: -1,
            // 按钮权限
            menuManager_btn_add: false,
            menuManager_btn_edit: false,
            menuManager_btn_del: false,
            // 表单校验规则
            rules: {
                permission: [
                    {
                        required: true,
                        message: '输入内容不能为空',
                        trigger: 'blur'
                    }
                ],
                menuId: [
                    {
                        required: true,
                        message: '节点ID不合法',
                        trigger: 'blur'
                    }
                ],
                name: [
                    {
                        required: this.setName,
                        message: '输入内容不能为空',
                        trigger: 'blur'
                    }
                ],
                type: [{ required: true, message: '类型不合法', trigger: 'blur' }],
                path: [{ required: true, validator: this.checkPath, trigger: 'blur' }],
                sort: [
                    {
                        validator: this.validateSort,
                        trigger: 'blur'
                    }
                ]
            }
        };
    },

    computed: {
        ...mapGetters(['elements', 'permissions'])
    },
    created() {
        this.getList();
        this.menuManager_btn_add = this.permissions['sys_menu_add'];
        this.menuManager_btn_edit = this.permissions['sys_menu_edit'];
        this.menuManager_btn_del = this.permissions['sys_menu_del'];
    },
    methods: {
        // 获取表格数据
        getList() {
            this.loading = true;
            fetchMenuTree(this.listQuery)
                .then((response) => {
                    if (response.data.code != 0) return;
                    this.treeData = response.data.data;
                    this.loading = false;
                })
                .catch(() => {
                    this.loading = false;
                });
        },
        // 树组件过滤规则
        filterNode(value, data) {
            if (!value) return true;
            return data.label.indexOf(value) !== -1;
        },
        // 节点展开逻辑
        nodeExpand(data) {
            const aChildren = data.children;
            if (aChildren.length > 0) {
                this.oExpandedKey[data.id] = true;
                this.oTreeNodeChildren[data.id] = aChildren;
            }
            this.setExpandedKeys();
        },
        nodeCollapse(data) {
            this.oExpandedKey[data.id] = false;
            // 如果有子节点
            this.treeRecursion(this.oTreeNodeChildren[data.id], (oNode) => {
                this.oExpandedKey[oNode.id] = false;
            });
            this.setExpandedKeys();
        },
        // 设置节点数据的key
        setExpandedKeys() {
            const oTemp = this.oExpandedKey;
            this.aExpandedKeys = [];
            for (const sKey in oTemp) {
                if (oTemp[sKey]) {
                    this.aExpandedKeys.push(parseInt(sKey));
                }
            }
        },
        // 设置节点数据的key
        treeRecursion(aChildren, fnCallback) {
            if (aChildren) {
                for (let i = 0; i < aChildren.length; ++i) {
                    const oNode = aChildren[i];
                    fnCallback && fnCallback(oNode);
                    this.treeRecursion(oNode.children, fnCallback);
                }
            }
        },
        // 点击节点
        getNodeData(data) {
            this.isEdit = true;
            this.$refs.form.clearValidate(); // 清除表单校验
            if (!this.formEdit) {
                this.formStatus = 'update';
            }
            getObj(data.id).then((response) => {
                this.form = response.data.data;
                this.nodeType = response.data.data.type;
                this.tempForm = JSON.parse(JSON.stringify(response.data.data));
            });
            this.currentId = data.id;
            this.onCancel();
        },
        // 检查path
        checkPath(rule, value, callback) {
            if (this.form.type === '1') {
                callback();
            } else if (this.validatenull(value)) {
                callback(new Error('请输入前端组件'));
            } else {
                callback();
            }
        },
        // 检查name
        setName(rule, value, callback) {
            if (this.form.name.length < 1) {
                callback(new Error('请输入内容'));
            } else if (this.form.name.length > 20) {
                callback(new Error('内容过长'));
            } else {
                callback();
            }
        },
        // 点击编辑
        handlerEdit() {
            this.isEdit = true;
            if (this.form.menuId) {
                this.formEdit = false;
                this.formStatus = 'update';
                this.form = JSON.parse(JSON.stringify(this.tempForm));
            }
        },
        // 点击新增
        handlerAdd() {
            if (this.nodeType == '1') {
                this.$notify({
                    title: '禁止',
                    message: '按钮不能添加子级内容',
                    type: 'info',
                    duration: 2000
                });
                return;
            }
            this.isEdit = false;
            this.resetForm();
            this.formEdit = false;
            this.formStatus = 'create';
        },
        // 点击删除
        handleDelete() {
            if (this.currentId === -1) return;
            this.$confirm('此操作将永久删除, 是否继续?', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            })
                .then(() => {
                    delObj(this.currentId).then(() => {
                        this.getList();
                        this.resetForm();
                        this.onCancel();
                        this.$notify({
                            title: '成功',
                            message: '删除成功',
                            type: 'success',
                            duration: 2000
                        });
                    });
                })
                .catch(() => {});
        },
        // 点击更新确定
        update() {
            this.$refs.form.validate((valid) => {
                if (valid) {
                    putObj(this.form).then(() => {
                        this.getList();
                        this.formEdit = false;
                        this.$notify({
                            title: '成功',
                            message: '更新成功',
                            type: 'success',
                            duration: 2000
                        });
                    });
                }
            });
        },
        // 点击创建确定
        create() {
            this.$refs.form.validate((valid) => {
                if (valid) {
                    addObj(this.form).then((res) => {
                        if (res.data.code === 0) {
                            this.getList();
                            this.formEdit = false;
                            this.$notify({
                                title: '成功',
                                message: '创建成功',
                                type: 'success',
                                duration: 2000
                            });
                            this.onCancel();
                        }
                    });
                }
            });
        },
        // 点击取消
        onCancel() {
            this.formEdit = true;
            this.isEdit = false;
            this.formStatus = '';
            this.form = this.tempForm;
            this.$refs.form.clearValidate(); // 清除表单校验
        },
        // 重置
        resetForm() {
            this.form = {
                permission: undefined,
                name: undefined,
                menuId: undefined,
                parentId: this.currentId,
                icon: undefined,
                sort: undefined,
                component: undefined,
                type: undefined,
                path: undefined
            };
        },
        // 排序校验
        validateSort(rule, value, callback) {
            if (value) {
                //正则
                const patt = /^-\d{1,3}$|^\d{1,3}$/;
                //检测排序输入
                if (patt.test(value)) {
                    callback();
                } else {
                    callback(new Error('排序值只能在-999到999之间！'));
                }
            } else {
                callback();
            }
        }
    }
};
</script>
<style lang="scss" scoped>
.madp-mt {
    margin-top: 15px;
}
</style>
